function Viewpoint(){
  this.name = null;
  this.uri = null;

  this.actors = new Array();
  this.topics = new Array();
};

Viewpoint.prototype.toXml = function() {
  var xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
  xmlStr += "<viewpoint ";
  if(this.uri != null && this.uri.trim() != "")
    xmlStr += "href=\"" + this.uri + "\" ";
  if(this.name != null && this.name.trim() != "")
    xmlStr += "name=\"" + this.name + "\" ";
  xmlStr += ">";

  for(i = 0; i < this.actors.length; i++){
    var href, name, role;
    if ('undefined' == typeof this.actors[i].href)
      href = "";
    else
      href = this.actors[i].href + "";
    if ('undefined' == typeof this.actors[i].name)
      name = "";
    else
      name = this.actors[i].name + "";
    if ('undefined' == typeof this.actors[i].role)
      role = "reader";
    else
      role = this.actors[i].role + "";
    xmlStr += "<actor href=\"" + href.toXml() + "\" name=\"" + name.toXml() + "\" role=\"" + role.toXml() + "\" />";
  }

  for(i = 0; i < this.topics.length; i++){
    var href, name;
    if ('undefined' == typeof this.topics[i].href)
      href = "";
    else
      href = this.topics[i].href + "";
    if ('undefined' == typeof this.topics[i].name)
      name = "";
    else
      name = this.topics[i].name + "";
    xmlStr += "<topic href=\"" + href.toXml() + "\">" + name.toXml() + "</topic>";
  }
  xmlStr += "</viewpoint>";
  return xmlStr;
}

Viewpoint.prototype.parseXml = function(xmlStr){
  var vp = new Viewpoint();
  var xmlReader = Components.classes["@mozilla.org/saxparser/xmlreader;1"]
                          .createInstance(Components.interfaces.nsISAXXMLReader);
  xmlReader.contentHandler = {
    currentElement: null,
    tmpTopic: null,

    startDocument: function() {},
		endDocument: function() {},

    startElement: function(uri, localName, qName, /*nsISAXAttributes*/ attributes) {
      this.currentElement = qName;
      //debug("[startElement] currentElement:" + this.currentElement ,1);

      if(qName == "viewpoint")
        for(var i=0; i<attributes.length; i++) {
          if(attributes.getQName(i) == "name")
            vp.name = attributes.getValue(i);
          if(attributes.getQName(i) == "href")
            vp.uri = attributes.getValue(i);
        }
      if(qName == "actor"){
        var actor = {};
        for(var i=0; i<attributes.length; i++) {
          if(attributes.getQName(i) == "href")
            actor.href = attributes.getValue(i);
          if(attributes.getQName(i) == "name")
            actor.name = attributes.getValue(i);
          if(attributes.getQName(i) == "role")
            actor.role = attributes.getValue(i);
        }
        vp.actors.push(actor);
      }
      if(qName == "topic"){
        this.tmpTopic = {};
        this.tmpTopic.name = "";
        for(var i=0; i<attributes.length; i++)
          if(attributes.getQName(i) == "href")
            this.tmpTopic.href = attributes.getValue(i);
        //debug("[startElement] this.tmpTopic.href:" + this.tmpTopic.href ,1);
      }
    },

    endElement: function(uri, localName, qName) {
      //debug("[endElement] currentElement:" + this.currentElement + ", typeof:" + (typeof this.tmpTopic),1);
      if(this.currentElement == "topic" && this.tmpTopic != null){
        vp.topics.push(this.tmpTopic);
        this.tmpTopic = null;
        //debug("[endElement] vp.topics.push:" + vp.topics.length ,1);
      }
      this.currentElement = null;
    },

    characters: function(value) {
      //debug("[characters] currentElement:" + this.currentElement + ", typeof:" + (typeof this.currentElement) + ", value:" + value,1);
      if((typeof this.currentElement) != "string")
        return;
      if(this.currentElement == "topic"){
        this.tmpTopic.name = value;
        //debug("[startElement] this.tmpTopic.name:" + this.tmpTopic.name ,1);
      }
    },
    processingInstruction: function(target, data) {},
    ignorableWhitespace: function(whitespace) {},
    startPrefixMapping: function(prefix, uri) {},
    endPrefixMapping: function(prefix) {},

    // nsISupports
    QueryInterface: function(iid) {
      if(!iid.equals(Components.interfaces.nsISupports) &&
         !iid.equals(Components.interfaces.nsISAXContentHandler))
        throw Components.results.NS_ERROR_NO_INTERFACE;
      return this;
    }
  }
  xmlReader.parseFromString(xmlStr, "text/xml");
  return vp;
}

Viewpoint.prototype.httpGet = function(user,pass) {
	if(this.uri == null){
		return null;
	}
	var req = new customRequest('GET', this.uri, "");
	var http = new HTTPCore();
	if(typeof user == "string" && user != "")
	  http.auth(user, pass);

	var res = http.doOperation(req);
	if(!res) return false;
	debug("[viewpoint.js] Viewpoint.httpGet URL:" + this.uri, 1);
	debug("[viewpoint.js] Viewpoint.httpGet Response:" + http.response, 1);
	var res = this.parseXml(http.response);
	if(res != null)
	  res.uri = this.uri;
	return res;
}

Viewpoint.prototype.httpPost = function(uri, user, pass) {
	if(uri == null){
		return false;
	}
	var content = this.toXml();
  var req = new customRequest('POST', uri, content);
  var http = new HTTPCore();
	if(typeof user == "string" && user != "")
	  http.auth(user, pass);
	var res = http.doOperation(req);
	if(!res) return false;
	var viewpointUri = http.xmlHttp.getResponseHeader("Location");

	debug("[viewpoint.js::httpPost] get res header:" + http.status, 1);
	debug("[viewpoint.js::httpPost] get res body:" + http.response, 1);
	debug("[viewpoint.js::httpPost] new viewpoint Uri:" + viewpointUri, 1);
	return viewpointUri;
}

function toXmlTest(){
  var v = new Viewpoint();
  v.name = "test viewpoint";
  v.uri = "http://test.hypertopic.org/argos/viewpoint/1/";

  var actor = {};
  actor.href = "http://tech-ada.utt.fr/actor/linux+fans/";
  actor.name = "actor name";
  v.actors.push(actor);

  var topic = {};
  topic.href = "http://test.hypertopic.org/argos/viewpoint/1/topic/2/";
  topic.name = "topic #2";
  v.topics.push(topic);
  var topic = {};
  topic.href = "http://test.hypertopic.org/argos/viewpoint/1/topic/3/";
  topic.name = "topic #3";
  v.topics.push(topic);

  return v.toXml();
}

function parseXmlTest(){
  var xmlStr =   '<?xml version="1.0" encoding="UTF-8"?>'
                +'<!DOCTYPE viewpoint SYSTEM "http://tech-ada.utt.fr/validator/dtd/viewpoint.dtd">'
                +'<viewpoint name="Software features">'
                +'   <actor href="http://tech-ada.utt.fr/actor/linux+fans/" name="linux fans" role="read" />'
                +'   <topic href="http://tech-ada.utt.fr/viewpoint/1/topic/1/">World Wide Web</topic>'
                +'</viewpoint>';
  var v = new Viewpoint();
  v = v.parseXml(xmlStr);
  dumpViewpoint(v);
}

function httpGetTest(){
  var v = new Viewpoint();
  v.uri = "http://test.hypertopic.org/argos/viewpoint/1/";
  //debug("viewpoint url before:" + v.uri,1);
  v = v.httpGet();
  dumpViewpoint(v);
}

function dumpViewpoint(v){
  debug("viewpoint name:" + v.name,1);
  debug("viewpoint uri:" + v.uri,1);
  for(var i =0; i <v.actors.length; i++){
	  var actor = v.actors[i];
	  debug("[actor] href:" + actor.href + ", name:" + actor.name + ", role:" + actor.role);
	}
  for(var i =0; i <v.topics.length; i++){
	  var topic = v.topics[i];
	  debug("[topic] href:" + topic.href + ", name:" + topic.name);
	}
}